/*工厂模式*/
#include <iostream>
#include <string>
#include <memory>
using namespace std;

// class Fruit
// {
// public:
//     Fruit() {}
//     virtual void show() = 0; //纯虚函数
// };

// class Apple : public Fruit
// {
// public:
//     Apple() {}
//     void show() override
//     {
//         cout<<"这是一个苹果!"<<endl;
//     }
// };

// class Banana : public Fruit
// {
// public:
//     Banana() {}
//         void show() override
//     {
//         cout<<"这是一个香蕉!"<<endl;
//     }
// };

//简单工厂模式
// class FruitFactory
// {
// public:
//     static shared_ptr<Fruit> create(const string& name)
//     {
//         if(name == "苹果")
//             return make_shared<Apple>(); //返回一个Apple类型改造的shared_ptr对象
//         else if(name == "香蕉")
//             return make_shared<Banana>();
//         //else if(name == ....) 每增加一种水果就要修改工厂代码结构
//     }
// };

// int main()
// {
//     shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
//     fruit->show();
//     fruit = FruitFactory::create("香蕉");
//     fruit->show();
//     return 0;
// }

//工厂方法模式
//抽象工厂类 - 一个工厂只负责生产一个商品
// class FruitFactory
// {
// public:
//     virtual shared_ptr<Fruit> create() = 0;
// };

// class AppleFactory : public FruitFactory
// {
// public:
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory
// {
// public:
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Banana>();
//     }
// };

// int main()
// {
//     shared_ptr<FruitFactory> factory(new AppleFactory);
//     shared_ptr<Fruit> fruit(factory->create());
//     fruit->show();
//     factory.reset(new BananaFactory); //切换管理对象
//     fruit = factory->create();
//     fruit->show();
//     return 0;
// }


//抽象工厂模式
//对象抽象类 - 对象类1 对象类2
//对象工厂抽象类 - 创建对象类1 创建对象类2
//工厂创建抽象类(生产对应产品的工厂) - 对象工厂创建类1 对象工厂创建类2
class Fruit //水果类
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        cout<<"苹果"<<endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        cout<<"香蕉"<<endl;
    }
};

class Animal //动物类
{
public:
    virtual void name() = 0;
};

class Dog : public Animal
{
public:
    void name() override
    {
        cout<<"修狗"<<endl;
    }
};

class Lamp : public Animal
{
public:
    void name() override
    {
        cout<<"小羊"<<endl;
    }
};

class Factory
{
public:
    virtual shared_ptr<Fruit> getFruit(const string&) = 0;
    virtual shared_ptr<Animal> getAnimal(const string&) = 0;
};

//水果创建类
class FruitFactory : public Factory
{
public:
    shared_ptr<Fruit> getFruit(const string& s) override 
    {
        if(s == "苹果")
            return make_shared<Apple>();
        else if(s == "香蕉")
            return make_shared<Banana>();
    }
    shared_ptr<Animal> getAnimal(const string& s) override { return nullptr; }
};

//动物创建类
class AnimalFactory : public Factory
{
public:
    shared_ptr<Fruit> getFruit(const string& s) override { return nullptr; }
    shared_ptr<Animal> getAnimal(const string& s) override
    {
        if(s == "小狗")
            return make_shared<Dog>();
        else if(s == "小羊")
            return make_shared<Lamp>();
    }
};

//工厂创建类
class FactoryProducer
{
public:
    static shared_ptr<Factory> create(const string& s)
    {
        if(s == "动物")
            return make_shared<AnimalFactory>();
        else if(s == "水果")
            return make_shared<FruitFactory>();
    }
};

int main()
{
    //获取水果工厂
    shared_ptr<Factory> factory = FactoryProducer::create("水果");
    //获取工厂需要生产的水果
    shared_ptr<Fruit> fruit = factory->getFruit("苹果");
    fruit->name();
    fruit = factory->getFruit("香蕉");
    fruit->name();

    factory = FactoryProducer::create("动物");
    shared_ptr<Animal> animal = factory->getAnimal("小狗");
    animal->name();
    animal = factory->getAnimal("小羊");
    animal->name();
    return 0;
}